package com.example.backend.service;

import com.example.backend.domain.entity.User;
import com.example.backend.domain.enums.TicketStatusTrackingType;
import com.example.backend.repository.TicketRepository;
import com.example.backend.repository.UserRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import jakarta.servlet.http.HttpServletRequest;

/**
 * 工单状态跟踪集成服务
 * 在工单操作时自动记录状态跟踪信息
 */
@Service
@Transactional
public class TicketTrackingIntegrationService {
    
    private static final Logger logger = LoggerFactory.getLogger(TicketTrackingIntegrationService.class);
    
    @Autowired
    private TicketStatusTrackingService trackingService;
    
    @Autowired
    private TicketRepository ticketRepository;
    
    @Autowired
    private UserRepository userRepository;
    
    /**
     * 记录工单创建跟踪
     */
    public void recordTicketCreation(Long ticketId, Long operatorId, HttpServletRequest request) {
        try {
            String ipAddress = getClientIpAddress(request);
            String userAgent = request.getHeader("User-Agent");
            
            trackingService.recordCreation(ticketId, operatorId, "工单已创建", ipAddress);
            logger.info("记录工单创建跟踪: ticketId={}, operatorId={}", ticketId, operatorId);
        } catch (Exception e) {
            logger.error("记录工单创建跟踪失败: ticketId={}, error={}", ticketId, e.getMessage());
        }
    }
    
    /**
     * 记录工单状态变更跟踪
     */
    public void recordStatusChange(Long ticketId, String oldStatus, String newStatus, 
                                  Long operatorId, String note, HttpServletRequest request) {
        try {
            String ipAddress = getClientIpAddress(request);
            String description = String.format("工单状态从 %s 变更为 %s", 
                                              translateStatus(oldStatus), translateStatus(newStatus));
            if (note != null && !note.trim().isEmpty()) {
                description += "，备注：" + note;
            }
            
            trackingService.recordStatusChange(ticketId, oldStatus, newStatus, operatorId, description, ipAddress);
            logger.info("记录工单状态变更跟踪: ticketId={}, {} -> {}, operatorId={}", 
                       ticketId, oldStatus, newStatus, operatorId);
        } catch (Exception e) {
            logger.error("记录工单状态变更跟踪失败: ticketId={}, error={}", ticketId, e.getMessage());
        }
    }
    
    /**
     * 记录工单优先级变更跟踪
     */
    public void recordPriorityChange(Long ticketId, String oldPriority, String newPriority, 
                                   Long operatorId, HttpServletRequest request) {
        try {
            String ipAddress = getClientIpAddress(request);
            String description = String.format("工单优先级从 %s 变更为 %s", 
                                              translatePriority(oldPriority), translatePriority(newPriority));
            
            trackingService.recordPriorityChange(ticketId, oldPriority, newPriority, operatorId, description, ipAddress);
            logger.info("记录工单优先级变更跟踪: ticketId={}, {} -> {}, operatorId={}", 
                       ticketId, oldPriority, newPriority, operatorId);
        } catch (Exception e) {
            logger.error("记录工单优先级变更跟踪失败: ticketId={}, error={}", ticketId, e.getMessage());
        }
    }
    
    /**
     * 记录工单分配跟踪
     */
    public void recordAssignment(Long ticketId, Long oldAssigneeId, Long newAssigneeId, 
                               Long operatorId, HttpServletRequest request) {
        try {
            String ipAddress = getClientIpAddress(request);
            String oldAssigneeName = getAssigneeName(oldAssigneeId);
            String newAssigneeName = getAssigneeName(newAssigneeId);
            
            String description;
            if (oldAssigneeId == null) {
                description = String.format("工单已分配给 %s", newAssigneeName);
            } else {
                description = String.format("工单从 %s 重新分配给 %s", oldAssigneeName, newAssigneeName);
            }
            
            trackingService.recordAssignment(ticketId, oldAssigneeName, newAssigneeName, operatorId, description, ipAddress);
            logger.info("记录工单分配跟踪: ticketId={}, {} -> {}, operatorId={}", 
                       ticketId, oldAssigneeName, newAssigneeName, operatorId);
        } catch (Exception e) {
            logger.error("记录工单分配跟踪失败: ticketId={}, error={}", ticketId, e.getMessage());
        }
    }
    
    /**
     * 记录工单解决跟踪
     */
    public void recordResolution(Long ticketId, Long operatorId, String resolution, HttpServletRequest request) {
        try {
            String ipAddress = getClientIpAddress(request);
            String description = "工单已解决";
            if (resolution != null && !resolution.trim().isEmpty()) {
                description += "，解决方案：" + resolution;
            }
            
            trackingService.recordResolution(ticketId, operatorId, description, ipAddress);
            logger.info("记录工单解决跟踪: ticketId={}, operatorId={}", ticketId, operatorId);
        } catch (Exception e) {
            logger.error("记录工单解决跟踪失败: ticketId={}, error={}", ticketId, e.getMessage());
        }
    }
    
    /**
     * 记录工单关闭跟踪
     */
    public void recordClosure(Long ticketId, Long operatorId, String reason, HttpServletRequest request) {
        try {
            String ipAddress = getClientIpAddress(request);
            String description = "工单已关闭";
            if (reason != null && !reason.trim().isEmpty()) {
                description += "，关闭原因：" + reason;
            }
            
            trackingService.recordClosure(ticketId, operatorId, description, ipAddress);
            logger.info("记录工单关闭跟踪: ticketId={}, operatorId={}", ticketId, operatorId);
        } catch (Exception e) {
            logger.error("记录工单关闭跟踪失败: ticketId={}, error={}", ticketId, e.getMessage());
        }
    }
    
    /**
     * 记录评论添加跟踪
     */
    public void recordCommentAdded(Long ticketId, Long operatorId, String commentType, HttpServletRequest request) {
        try {
            String ipAddress = getClientIpAddress(request);
            String description = "INTERNAL".equals(commentType) ? "添加了内部评论" : "添加了公开评论";
            
            trackingService.recordCommentAdded(ticketId, operatorId, description, ipAddress);
            logger.info("记录评论添加跟踪: ticketId={}, operatorId={}, type={}", ticketId, operatorId, commentType);
        } catch (Exception e) {
            logger.error("记录评论添加跟踪失败: ticketId={}, error={}", ticketId, e.getMessage());
        }
    }
    
    /**
     * 记录附件添加跟踪
     */
    public void recordAttachmentAdded(Long ticketId, Long operatorId, String fileName, HttpServletRequest request) {
        try {
            String ipAddress = getClientIpAddress(request);
            trackingService.recordAttachmentAdded(ticketId, operatorId, fileName, ipAddress);
            logger.info("记录附件添加跟踪: ticketId={}, operatorId={}, fileName={}", ticketId, operatorId, fileName);
        } catch (Exception e) {
            logger.error("记录附件添加跟踪失败: ticketId={}, error={}", ticketId, e.getMessage());
        }
    }
    
    /**
     * 记录工单升级跟踪
     */
    public void recordEscalation(Long ticketId, Long operatorId, String reason, HttpServletRequest request) {
        try {
            String ipAddress = getClientIpAddress(request);
            String description = "工单已升级";
            if (reason != null && !reason.trim().isEmpty()) {
                description += "，升级原因：" + reason;
            }
            
            trackingService.recordTracking(ticketId, TicketStatusTrackingType.ESCALATED, 
                                         null, "ESCALATED", "escalation", description, 
                                         operatorId, ipAddress, null, false, true);
            logger.info("记录工单升级跟踪: ticketId={}, operatorId={}", ticketId, operatorId);
        } catch (Exception e) {
            logger.error("记录工单升级跟踪失败: ticketId={}, error={}", ticketId, e.getMessage());
        }
    }
    
    /**
     * 记录工单重新打开跟踪
     */
    public void recordReopening(Long ticketId, Long operatorId, String reason, HttpServletRequest request) {
        try {
            String ipAddress = getClientIpAddress(request);
            String description = "工单已重新打开";
            if (reason != null && !reason.trim().isEmpty()) {
                description += "，重新打开原因：" + reason;
            }
            
            trackingService.recordTracking(ticketId, TicketStatusTrackingType.REOPENED, 
                                         "CLOSED", "OPEN", "status", description, 
                                         operatorId, ipAddress, null, false, true);
            logger.info("记录工单重新打开跟踪: ticketId={}, operatorId={}", ticketId, operatorId);
        } catch (Exception e) {
            logger.error("记录工单重新打开跟踪失败: ticketId={}, error={}", ticketId, e.getMessage());
        }
    }
    
    /**
     * 获取客户端IP地址
     */
    private String getClientIpAddress(HttpServletRequest request) {
        if (request == null) return "unknown";
        
        String xForwardedFor = request.getHeader("X-Forwarded-For");
        if (xForwardedFor != null && !xForwardedFor.isEmpty() && !"unknown".equalsIgnoreCase(xForwardedFor)) {
            return xForwardedFor.split(",")[0].trim();
        }
        
        String xRealIp = request.getHeader("X-Real-IP");
        if (xRealIp != null && !xRealIp.isEmpty() && !"unknown".equalsIgnoreCase(xRealIp)) {
            return xRealIp;
        }
        
        return request.getRemoteAddr();
    }
    
    /**
     * 获取分配人姓名
     */
    private String getAssigneeName(Long assigneeId) {
        if (assigneeId == null) return "未分配";
        
        try {
            User user = userRepository.findById(assigneeId).orElse(null);
            return user != null ? user.getFullName() : "未知用户";
        } catch (Exception e) {
            logger.warn("获取分配人姓名失败: assigneeId={}, error={}", assigneeId, e.getMessage());
            return "未知用户";
        }
    }
    
    /**
     * 翻译状态
     */
    private String translateStatus(String status) {
        if (status == null) return "未知";
        
        switch (status) {
            case "OPEN": return "待处理";
            case "IN_PROGRESS": return "处理中";
            case "PENDING": return "等待中";
            case "RESOLVED": return "已解决";
            case "CLOSED": return "已关闭";
            case "CANCELLED": return "已取消";
            default: return status;
        }
    }
    
    /**
     * 翻译优先级
     */
    private String translatePriority(String priority) {
        if (priority == null) return "未知";
        
        switch (priority) {
            case "LOW": return "低";
            case "MEDIUM": return "中";
            case "HIGH": return "高";
            case "URGENT": return "紧急";
            case "CRITICAL": return "严重";
            default: return priority;
        }
    }
}

